package com.xindacloud.sms.portal.utils;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.Objects;

public class ExcelExportUtil {

    public static void exportExcel(String[] columns, List<?> dataList, String sheetName, OutputStream os) throws IOException, IllegalAccessException {
        // Create a Workbook
        Workbook workbook = new XSSFWorkbook(); // new HSSFWorkbook() for generating `.xls` file

        /* CreationHelper helps us create instances of various things like DataFormat,
           Hyperlink, RichTextString etc, in a format (HSSF, XSSF) independent way */
        CreationHelper createHelper = workbook.getCreationHelper();
        // Create a Sheet
        Sheet sheet = workbook.createSheet(sheetName);

        // Create a Font for styling header cells
        Font headerFont = workbook.createFont();
        headerFont.setBold(true);
        headerFont.setFontHeightInPoints((short) 14);
        headerFont.setColor(IndexedColors.BLACK1.getIndex());

        // Create a CellStyle with the font
        CellStyle headerCellStyle = workbook.createCellStyle();
        headerCellStyle.setFont(headerFont);

        // Create a Row
        Row headerRow = sheet.createRow(0);

        // Create cells
        for (int i = 0; i < columns.length; i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(columns[i]);
            cell.setCellStyle(headerCellStyle);
        }
        // Create Cell Style for formatting Date
        CellStyle dateCellStyle = workbook.createCellStyle();
        dateCellStyle.setDataFormat(createHelper.createDataFormat().getFormat("yyyy-MM-dd HH:mm:ss"));
        // Create Other rows and cells with employees data
        int rowNum = 1;
        //创建表格数据
        Field[] fields;
        for (Object obj : dataList) {
            fields = obj.getClass().getDeclaredFields();
            Row row = sheet.createRow(rowNum++);
            int j = 0;
            for (Field f : fields) {
                f.setAccessible(true);
                Object cellValue = f.get(obj);
                if (Objects.isNull(cellValue)) {
                    cellValue = "";
                }
                final String type = cellValue.getClass().getTypeName();
                switch (type) {
                    case "char":
                    case "java.lang.Character":
                    case "java.lang.String":
                        row.createCell(j).setCellValue(cellValue.toString());
                        break;
                    case "java.util.Date":
                        final Cell dateCell = row.createCell(j);
                        dateCell.setCellValue((Date) cellValue);
                        dateCell.setCellStyle(dateCellStyle);
                        break;
                    case "java.time.LocalDateTime":
                        final Cell localDateTimeCell = row.createCell(j);
                        final LocalDateTime localDateTime = (LocalDateTime) cellValue;
                        final Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
                        localDateTimeCell.setCellValue(date);
                        localDateTimeCell.setCellStyle(dateCellStyle);
                        break;
                    case "java.lang.Integer":
                        row.createCell(j).setCellValue(Integer.valueOf(cellValue.toString()));
                        break;
                    case "int":
                        row.createCell(j).setCellValue(Integer.valueOf(cellValue.toString()));
                        break;
                    case "float":
                        row.createCell(j).setCellValue(Double.valueOf(cellValue.toString()));
                        break;
                    case "double":
                        row.createCell(j).setCellValue(Double.valueOf(cellValue.toString()));
                        break;
                    case "java.lang.Double":
                        row.createCell(j).setCellValue(Double.valueOf(cellValue.toString()));
                        break;
                    case "java.lang.Float":
                        row.createCell(j).setCellValue(Double.valueOf(cellValue.toString()));
                        break;
                    case "java.lang.Long":
                        row.createCell(j).setCellValue(Long.valueOf(cellValue.toString()));
                        break;
                    case "java.math.BigDecimal":
                        row.createCell(j).setCellValue(Double.valueOf(cellValue.toString()));
                        break;
                    default:
                        break;
                }

                j++;
            }

        }

        // Resize all columns to fit the content size
        for (int i = 0; i < columns.length; i++) {
            sheet.autoSizeColumn(i);
        }
        workbook.write(os);
        os.close();
        // Closing the workbook
        workbook.close();
    }

}
